﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Tunneler.Tools;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Tunneler {
    class LaserShot : IGameObject {
        World world;

        static Texture2D texture;
        static Color[] textureData;
        static Vector2 origin;
        Vector2 source;
        Vector2 position;

        const float maxRange = 1000;

        public const int Damage = 20;

        public Vector2 Position { get { return position; } set { this.position = value; } }
        public Vector2 Velocity { get; set; }
        public float Rotation { get; set; }
        public Vector2 Origin { get { return origin; } }
        public Texture2D Texture { get { return texture; } }
        public Color[] TextureData { get { return textureData; } }
        public float TextureScale { get { return 1f; } }

        /// <summary>
        /// Use LazerShot(Vector2) for normal usage. This is a hack to call LoadContent method.
        /// </summary>
        public LaserShot() {
        }

        public LaserShot(World world, Vector2 firedFrom) {
            this.world = world;
            source = firedFrom;
        }

        public void Update(GameTime gameTime) {
            Position += Velocity;

            if (IsTooFar() || IsNotOnMap()) {
                KillSelf();
            }
        }

        public void Draw(SpriteBatch spriteBatch) {
            spriteBatch.Draw(Texture, Position, null, Color.White, Rotation, Origin, TextureScale, SpriteEffects.None, 0);
        }

        public void LoadContent(ContentManager content) {
            if (texture == null) {
                texture = content.Load<Texture2D>("explosion1");
                origin = new Vector2(texture.Width / 2, texture.Height / 2);

                textureData = new Color[texture.Width * texture.Height];
                texture.GetData<Color>(textureData);

                Explosion e = new Explosion(position, Rotation);
                e.LoadContent(content);
            }
        }

        public void TouchedBy(IGameObject other) {
            if (other is Player) {
                Explode();
            } else if (other is PlayerBase) {
                KillSelf();
            }
        }

        public void TouchedBy(Terrain terrain) {
            Explode();
        }

        private bool IsTooFar() {
            return Vector2.Distance(source, Position) > maxRange;
        }

        private bool IsNotOnMap() {
            float widthOffset = texture.Width / 2 * TextureScale;
            float heightOffset = texture.Height / 2 * TextureScale;

            return (position.X < widthOffset || position.Y < heightOffset)
                ||
                ((position.X > world.Terrain.Width - widthOffset) || (position.Y > world.Terrain.Height - heightOffset));
        }

        private void Explode() {
            // Create Explosion
            Explosion e = new Explosion(Position, Rotation);
            world.RegisterGameObject(e);

            // Kill Itself
            KillSelf();
        }

        private void KillSelf() {
            world.DeleteGameObject(this);
        }
    }
}
